Loading Required Libraries

library(sf)
library(knitr)
library(BIOMASS)
library(ggplot2)
library(dplyr)
#old data
data_forAGB <- data_clean
#nrow(data_forAGB)
data_forAGB
#new data
new_data_for_AGB <- new_data_clean
new_data_for_AGB
#Checking and retrieving tree taxonomy
#old data

Taxo_old <- correctTaxo(
  genus = data_forAGB$Genus.species,
  useCache = TRUE, verbose = FALSE)

saveRDS(Taxo_old, file = "~/Remote-sensing/taxo_old_data.rsd")

data_forAGB$GenusCorrected <- Taxo$genusCorrected
data_forAGB$SpeciesCorrected <- Taxo$speciesCorrected
Taxo_new <- correctTaxo(
  genus = new_data_for_AGB$Genus_species,
  useCache = TRUE, verbose = FALSE)

saveRDS(Taxo_new, file = "~/Remote-sensing/taxo_new_data.rsd")

new_data_for_AGB$GenusCorrected <- Taxo_new$genusCorrected
new_data_for_AGB$SpeciesCorrected <- Taxo_new$speciesCorrected

#Retrieving Family and Order Information #APG (Angiosperm Phylogeny Group) family and order (optional)

APG_old <- getTaxonomy(data_forAGB$GenusCorrected, findOrder = TRUE)
data_forAGB$familyAPG <- APG_old$family
data_forAGB$orderAPG <- APG_old$order
APG_new <- getTaxonomy(new_data_for_AGB$GenusCorrected, findOrder = TRUE)
new_data_for_AGB$familyAPG <- APG_new$family
new_data_for_AGB$orderAPG <- APG_new$order

#Estimating Wood Density

wood_densities_old <- getWoodDensity(
  genus = data_forAGB$GenusCorrected,
  species = data_forAGB$SpeciesCorrected,
  stand = data_forAGB$Plot_name
)

# The reference dataset contains 16467 wood density values??

wood_densities_old
wood_densities_new <- getWoodDensity(
  genus = new_data_for_AGB$GenusCorrected,
  species = new_data_for_AGB$SpeciesCorrected,
  stand = new_data_for_AGB$Plot_name
)

wood_densities_new
#ดึงค่า meanWD จาก df wood_densities ไปใส่ใน df คอลัมน์ใหม่
data_forAGB$WD <- wood_densities_old$meanWD
new_data_for_AGB$WD <- wood_densities_new$meanWD
data_forAGB
new_data_for_AGB
# dataset ของเรา มีต้นไม้กี่ต้นที่ได้ค่า wood density จากแต่ละระดับ (species/genus/family)
sum(wood_densities_old$levelWD == "species")
[1] 7264
sum(wood_densities_old$levelWD == "genus")
[1] 195
sum(!wood_densities_old$levelWD %in% c("genus", "species"))
[1] 1072
# dataset ของเรา มีต้นไม้กี่ต้นที่ได้ค่า wood density จากแต่ละระดับ (species/genus/family)
sum(wood_densities_new$levelWD == "species")
[1] 7294
sum(wood_densities_new$levelWD == "genus")
[1] 195
sum(!wood_densities_new$levelWD %in% c("genus", "species"))
[1] 1067

#Checking Missing Values After Wood Density Assignment

#check missing value แต่ละคอลัมน์
colSums(is.na(data_forAGB))
       ExactDate        Plot_name          Quadrat              Tag          StemTag    Genus.species               QX 
               0                0                0                0                0                0                0 
              QY               PX               PY              DBH              HOM             Code   GenusCorrected 
               0                0                0                0               56             6298                0 
SpeciesCorrected        familyAPG         orderAPG               WD 
               0                9                9                0 
#check missing value แต่ละคอลัมน์
colSums(is.na(new_data_for_AGB))
       ExactDate        Plot_name          Quadrat              Tag          StemTag    Genus_species               QX 
               0                0                0                0                0                0                0 
              QY               PX               PY              DBH              HOM             Code       Note_Genus 
               0                0                0                0               56             1913                0 
  GenusCorrected SpeciesCorrected        familyAPG         orderAPG               WD 
               0                0                0                0                0 
#ดูว่ามีแถวไหนบ้างที่ missing
data_forAGB %>%
  filter(is.na(familyAPG) | is.na(orderAPG))
utm_conner <- read.csv("~/Remote-sensing/DATA/utm_corner.csv")
head(utm_conner)
conner_filtered <- utm_conner %>%
  filter(Plot_name == unique(data_forAGB$Plot_name) & X_loc == 0 & Y_loc == 0)

head(conner_filtered)
tree_data_old <- data_forAGB %>%
  left_join(conner_filtered, by = "Plot_name") %>%
  mutate(
    abs_x = X_UTM + PX,
    abs_y = Y_UTM + PY  
  ) %>%
  dplyr::select(abs_x, abs_y) 
tree_data_new <- new_data_for_AGB %>%
  left_join(conner_filtered, by = "Plot_name") %>%
  mutate(
    abs_x = X_UTM + PX,
    abs_y = Y_UTM + PY  
  ) %>%
  dplyr::select(abs_x, abs_y) 
tree_data_old
tree_data_new
old_tree_sf <- st_as_sf(tree_data_old, coords = c("abs_x", "abs_y"), crs = 32647)
new_tree_sf <- st_as_sf(tree_data_new, coords = c("abs_x", "abs_y"), crs = 32647)
old_tree_longlat <- st_transform(old_tree_sf, crs = 4326)
new_tree_longlat <- st_transform(new_tree_sf, crs = 4326)
coords_longlat_old <- st_coordinates(old_tree_longlat)
tree_data_old$lon <- coords_longlat_old[, 1]
tree_data_old$lat <- coords_longlat_old[, 2]

coords_longlat_new <- st_coordinates(new_tree_longlat)
tree_data_new$lon <- coords_longlat_new[, 1]
tree_data_new$lat <- coords_longlat_new[, 2]
coords_tree_old <- apply(tree_data_old[c("lon", "lat")], 2, mean)
coords_tree_new <- apply(tree_data_new[c("lon", "lat")], 2, mean)

Estimating Tree Height (H)

H_chave_old <- retrieveH(
  D = data_forAGB$DBH,
  coord = coords_tree_old
)
H_chave_new <- retrieveH(
  D = new_data_for_AGB$DBH,
  coord = coords_tree_new
)
data_forAGB$H_chave <- H_chave_old$H
new_data_for_AGB$H_chave <- H_chave_new$H
old_HD_model <- modelHD(
  D = data_forAGB$DBH,
  H = data_forAGB$H_chave,
  method = "log2",
  useWeight = TRUE
)
new_HD_model <- modelHD(
  D = new_data_for_AGB$DBH,
  H = new_data_for_AGB$H_chave,
  method = "log2",
  useWeight = TRUE
)

Computing Above Ground Biomass (AGB)

data_forAGB$AGB <- computeAGB(
  D = data_forAGB$DBH,
  WD = data_forAGB$WD,
  H = data_forAGB$H_chave 
)

new_data_for_AGB$AGB <- computeAGB(
  D = new_data_for_AGB$DBH,
  WD = new_data_for_AGB$WD,
  H = new_data_for_AGB$H_chave 
)

Propagating Errors in AGB Estimation (Monte Carlo)

D_error_prop_old <- AGBmonteCarlo(
  D = data_forAGB$DBH, WD = data_forAGB$WD, H = data_forAGB$H_chave,
  Dpropag = "chave2004",
  errWD = rep(0,nrow(data_forAGB)), errH = 0 
)

D_error_prop_new <- AGBmonteCarlo(
  D = new_data_for_AGB$DBH, WD = new_data_for_AGB$WD, H = new_data_for_AGB$H_chave,
  Dpropag = "chave2004",
  errWD = rep(0,nrow(new_data_for_AGB)), errH = 0 
)
new_data_for_AGB
WD_error_prop_old <- AGBmonteCarlo(
  D = data_forAGB$DBH, WD = data_forAGB$WD, H = data_forAGB$H_chave,
  errWD = wood_densities_old$sdWD,
  Dpropag = 0 , errH = 0 
)

WD_error_prop_new <- AGBmonteCarlo(
  D = new_data_for_AGB$DBH, WD = new_data_for_AGB$WD, H = new_data_for_AGB$H_chave,
  errWD = wood_densities_new$sdWD,
  Dpropag = 0 , errH = 0 
)
H_model_error_prop_old <- AGBmonteCarlo(
  D = data_forAGB$DBH, WD = data_forAGB$WD, 
  HDmodel = HD_model, 
  Dpropag = 0 , errWD = rep(0,nrow(data_forAGB)) 
)

H_model_error_prop_new <- AGBmonteCarlo(
  D = new_data_for_AGB$DBH, WD = new_data_for_AGB$WD, 
  HDmodel = HD_model, 
  Dpropag = 0 , errWD = rep(0,nrow(new_data_for_AGB)) 
)
error_prop_old <- AGBmonteCarlo(
  D = data_forAGB$DBH,
  WD =  data_forAGB$WD,        
  H =  data_forAGB$H_chave, 
  Dpropag = "chave2004",           
  errWD = wood_densities_old$sdWD,    
  errH = H_model_error_prop_old$sdAGB
)

error_prop_new <- AGBmonteCarlo(
  D = new_data_for_AGB$DBH,
  WD =  new_data_for_AGB$WD,        
  H =  new_data_for_AGB$H_chave, 
  Dpropag = "chave2004",           
  errWD = wood_densities_new$sdWD,    
  errH = H_model_error_prop_new$sdAGB
)
error_prop_old[(1:4)]
$meanAGB
[1] 2379.039

$medAGB
[1] 2378.968

$sdAGB
[1] 39.31173

$credibilityAGB
    2.5%    97.5% 
2303.432 2453.130 
sum(data_forAGB$AGB)
[1] 1839.656
error_prop_new[(1:4)]
$meanAGB
[1] 2405.423

$medAGB
[1] 2405.962

$sdAGB
[1] 41.77771

$credibilityAGB
    2.5%    97.5% 
2326.113 2487.241 
sum(new_data_for_AGB$AGB)
[1] 1845.819
old_AGB_by_plot <- summaryByPlot(AGB_val = error_prop_old$AGB_simu, plot = data_forAGB$Plot_name, drawPlot = TRUE)

new_AGB_by_plot <- summaryByPlot(AGB_val = error_prop_new$AGB_simu, plot = new_data_for_AGB$Plot_name, drawPlot = TRUE)

Plot Spatial Configuration and Subplot Division

Ranong_plot_corner <- utm_conner[utm_conner$Plot_name == "La-un (Ranong)",]
Ranong_plot_corner
fieldplot <- check_plot_coord(
  corner_data =  Ranong_plot_corner,
  proj_coord = c("X_UTM", "Y_UTM"),  
  rel_coord = c("X_loc", "Y_loc"),
  plot_ID = "Plot_name",
  trust_GPS_corners = FALSE,
  draw_plot = TRUE, rm_outliers = FALSE)

fieldplot_old <- check_plot_coord(
  corner_data =  Ranong_plot_corner,
  proj_coord = c("X_UTM", "Y_UTM"),  
  rel_coord = c("X_loc", "Y_loc"),
  plot_ID = "Plot_name",                      
  trust_GPS_corners = FALSE,
  tree_data = data_forAGB,
  tree_coords = c("PX", "PY"),
  tree_plot_ID = "Plot_name",           
  draw_plot = TRUE, 
  rm_outliers = FALSE
)

fieldplot_new <- check_plot_coord(
  corner_data =  Ranong_plot_corner,
  proj_coord = c("X_UTM", "Y_UTM"),  
  rel_coord = c("X_loc", "Y_loc"),
  plot_ID = "Plot_name",                      
  trust_GPS_corners = FALSE,
  tree_data = new_data_for_AGB,
  tree_coords = c("PX", "PY"),
  tree_plot_ID = "Plot_name",           
  draw_plot = TRUE, 
  rm_outliers = FALSE
)

st_write(
  obj = fieldplot_old$polygon,
  dsn = "~/Remote-sensing/Ranong_fieldplot_old.shp",
  delete_layer = TRUE
)
Deleting layer `Ranong_fieldplot_old' using driver `ESRI Shapefile'
Writing layer `Ranong_fieldplot_old' to data source 
  `/Users/pchwx/Remote-sensing/Ranong_fieldplot_old.shp' using driver `ESRI Shapefile'
Writing 1 features with 0 fields and geometry type Polygon.
st_write(
  obj = fieldplot_new$polygon,
  dsn = "~/Remote-sensing/Ranong_fieldplot_new.shp",
  delete_layer = TRUE
)
Deleting layer `Ranong_fieldplot_new' using driver `ESRI Shapefile'
Writing layer `Ranong_fieldplot_new' to data source 
  `/Users/pchwx/Remote-sensing/Ranong_fieldplot_new.shp' using driver `ESRI Shapefile'
Writing 1 features with 0 fields and geometry type Polygon.
# 20x20
subplots_grid20_old <- divide_plot(
  corner_data = fieldplot_old$corner_coord, 
  rel_coord = c("x_rel","y_rel"),
  proj_coord = c("x_proj","y_proj"),
  grid_size = 20,
  tree_data = data_forAGB, 
  tree_coords = c("PX","PY")
)

#50x50
subplots_grid50_old <- divide_plot(
  corner_data = fieldplot_old$corner_coord, 
  rel_coord = c("x_rel","y_rel"),
  proj_coord = c("x_proj","y_proj"),
  grid_size = 50,
  tree_data = data_forAGB, 
  tree_coords = c("PX","PY")
)
# 20x20
subplots_grid20_new <- divide_plot(
  corner_data = fieldplot_new$corner_coord, 
  rel_coord = c("x_rel","y_rel"),
  proj_coord = c("x_proj","y_proj"),
  grid_size = 20,
  tree_data = new_data_for_AGB, 
  tree_coords = c("PX","PY")
)

#50x50
subplots_grid50_new <- divide_plot(
  corner_data = fieldplot_old$corner_coord, 
  rel_coord = c("x_rel","y_rel"),
  proj_coord = c("x_proj","y_proj"),
  grid_size = 50,
  tree_data = data_forAGB, 
  tree_coords = c("PX","PY")
)
subplot_metric_perHA20_old <- subplot_summary(
  subplots = subplots_grid20_old,
  value = "AGB", 
  per_ha = TRUE)
[[1]]

subplot_metric_perHA20_new <- subplot_summary(
  subplots = subplots_grid20_new,
  value = "AGB", 
  per_ha = TRUE)
[[1]]

subplot_metric_perHA50_old <- subplot_summary(
  subplots = subplots_grid50_old,
  value = "AGB", 
  per_ha = TRUE)
[[1]]

subplot_metric_perHA50_new <- subplot_summary(
  subplots = subplots_grid50_new,
  value = "AGB", 
  per_ha = TRUE)
[[1]]

custom_plot_perHA20_old <- subplot_metric_perHA20_old$plot_design +
  scale_fill_distiller(palette = "YlGnBu", direction = 1) 

custom_plot_perHA20_old


sf::st_write(custom_plot_perHA20_old,"~/Remote-sensing/polygon_20m_perHA.shp")
Error in UseMethod("st_write") : 
  no applicable method for 'st_write' applied to an object of class "c('gg', 'ggplot')"
custom_plot_perHA20_new <- subplot_metric_perHA20_new$plot_design +
  scale_fill_distiller(palette = "YlGnBu", direction = 1)

custom_plot_perHA20_new

subplot_polygons20m_perHA <- sf::st_set_crs(
 subplot_metric_perHA20_new$polygon ,
  value = "EPSG:32647") 

sf::st_write(subplot_polygons20m_perHA,"~/Remote-sensing/polygon_20m_perHA.shp")
Writing layer `polygon_20m_perHA' to data source `/Users/pchwx/Remote-sensing/polygon_20m_perHA.shp' using driver `ESRI Shapefile'
Writing 225 features with 2 fields and geometry type Polygon.
custom_plot_perHA50_old <- subplot_metric_perHA50_old$plot_design +
  scale_fill_distiller(palette = "YlGnBu", direction = 1) 

custom_plot_perHA50_old

custom_plot_perHA50_new <- subplot_metric_perHA50_new$plot_design +
  scale_fill_distiller(palette = "YlGnBu", direction = 1)

custom_plot_perHA50_new

subplot_metric_sum20_old<- subplot_summary(
  subplots = subplots_grid20_old,
  value = "AGB",
  fun = quantile, probs = 0.5, 
  per_ha = FALSE)
[[1]]

custom_plot_qt <- subplot_metric_sum20_old$plot_design +
  scale_fill_distiller(palette = "YlGnBu", direction = 1)

custom_plot_qt

LS0tCnRpdGxlOiAiQWJvdmUgR3JvdW5kIEJpb21hc3MgKEFHQikgRXN0aW1hdGlvbiIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyMgTG9hZGluZyBSZXF1aXJlZCBMaWJyYXJpZXMKCmBgYHtyfQpsaWJyYXJ5KHNmKQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KEJJT01BU1MpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShkcGx5cikKYGBgCgoKYGBge3J9CiNvbGQgZGF0YQpkYXRhX2ZvckFHQiA8LSBkYXRhX2NsZWFuCiNucm93KGRhdGFfZm9yQUdCKQpkYXRhX2ZvckFHQgpgYGAKCmBgYHtyfQojbmV3IGRhdGEKbmV3X2RhdGFfZm9yX0FHQiA8LSBuZXdfZGF0YV9jbGVhbgpuZXdfZGF0YV9mb3JfQUdCCmBgYAoKCmBgYHtyfQojQ2hlY2tpbmcgYW5kIHJldHJpZXZpbmcgdHJlZSB0YXhvbm9teQojb2xkIGRhdGEKClRheG9fb2xkIDwtIGNvcnJlY3RUYXhvKAogIGdlbnVzID0gZGF0YV9mb3JBR0IkR2VudXMuc3BlY2llcywKICB1c2VDYWNoZSA9IFRSVUUsIHZlcmJvc2UgPSBGQUxTRSkKCnNhdmVSRFMoVGF4b19vbGQsIGZpbGUgPSAifi9SZW1vdGUtc2Vuc2luZy90YXhvX29sZF9kYXRhLnJzZCIpCgpkYXRhX2ZvckFHQiRHZW51c0NvcnJlY3RlZCA8LSBUYXhvJGdlbnVzQ29ycmVjdGVkCmRhdGFfZm9yQUdCJFNwZWNpZXNDb3JyZWN0ZWQgPC0gVGF4byRzcGVjaWVzQ29ycmVjdGVkCmBgYAoKYGBge3J9ClRheG9fbmV3IDwtIGNvcnJlY3RUYXhvKAogIGdlbnVzID0gbmV3X2RhdGFfZm9yX0FHQiRHZW51c19zcGVjaWVzLAogIHVzZUNhY2hlID0gVFJVRSwgdmVyYm9zZSA9IEZBTFNFKQoKc2F2ZVJEUyhUYXhvX25ldywgZmlsZSA9ICJ+L1JlbW90ZS1zZW5zaW5nL3RheG9fbmV3X2RhdGEucnNkIikKCm5ld19kYXRhX2Zvcl9BR0IkR2VudXNDb3JyZWN0ZWQgPC0gVGF4b19uZXckZ2VudXNDb3JyZWN0ZWQKbmV3X2RhdGFfZm9yX0FHQiRTcGVjaWVzQ29ycmVjdGVkIDwtIFRheG9fbmV3JHNwZWNpZXNDb3JyZWN0ZWQKYGBgCgoKI1JldHJpZXZpbmcgRmFtaWx5IGFuZCBPcmRlciBJbmZvcm1hdGlvbgogICNBUEcgKEFuZ2lvc3Blcm0gUGh5bG9nZW55IEdyb3VwKSBmYW1pbHkgYW5kIG9yZGVyIChvcHRpb25hbCkKCmBgYHtyfQpBUEdfb2xkIDwtIGdldFRheG9ub215KGRhdGFfZm9yQUdCJEdlbnVzQ29ycmVjdGVkLCBmaW5kT3JkZXIgPSBUUlVFKQpkYXRhX2ZvckFHQiRmYW1pbHlBUEcgPC0gQVBHX29sZCRmYW1pbHkKZGF0YV9mb3JBR0Ikb3JkZXJBUEcgPC0gQVBHX29sZCRvcmRlcgpgYGAKCmBgYHtyfQpBUEdfbmV3IDwtIGdldFRheG9ub215KG5ld19kYXRhX2Zvcl9BR0IkR2VudXNDb3JyZWN0ZWQsIGZpbmRPcmRlciA9IFRSVUUpCm5ld19kYXRhX2Zvcl9BR0IkZmFtaWx5QVBHIDwtIEFQR19uZXckZmFtaWx5Cm5ld19kYXRhX2Zvcl9BR0Ikb3JkZXJBUEcgPC0gQVBHX25ldyRvcmRlcgpgYGAKCgojRXN0aW1hdGluZyBXb29kIERlbnNpdHkKCmBgYHtyfQp3b29kX2RlbnNpdGllc19vbGQgPC0gZ2V0V29vZERlbnNpdHkoCiAgZ2VudXMgPSBkYXRhX2ZvckFHQiRHZW51c0NvcnJlY3RlZCwKICBzcGVjaWVzID0gZGF0YV9mb3JBR0IkU3BlY2llc0NvcnJlY3RlZCwKICBzdGFuZCA9IGRhdGFfZm9yQUdCJFBsb3RfbmFtZQopCgojIFRoZSByZWZlcmVuY2UgZGF0YXNldCBjb250YWlucyAxNjQ2NyB3b29kIGRlbnNpdHkgdmFsdWVzPz8KCndvb2RfZGVuc2l0aWVzX29sZApgYGAKCmBgYHtyfQp3b29kX2RlbnNpdGllc19uZXcgPC0gZ2V0V29vZERlbnNpdHkoCiAgZ2VudXMgPSBuZXdfZGF0YV9mb3JfQUdCJEdlbnVzQ29ycmVjdGVkLAogIHNwZWNpZXMgPSBuZXdfZGF0YV9mb3JfQUdCJFNwZWNpZXNDb3JyZWN0ZWQsCiAgc3RhbmQgPSBuZXdfZGF0YV9mb3JfQUdCJFBsb3RfbmFtZQopCgp3b29kX2RlbnNpdGllc19uZXcKYGBgCgoKCgpgYGB7cn0KI+C4lOC4tuC4h+C4hOC5iOC4siBtZWFuV0Qg4LiI4Liy4LiBIGRmIHdvb2RfZGVuc2l0aWVzIOC5hOC4m+C5g+C4quC5iOC5g+C4mSBkZiDguITguK3guKXguLHguKHguJnguYzguYPguKvguKHguYgKZGF0YV9mb3JBR0IkV0QgPC0gd29vZF9kZW5zaXRpZXNfb2xkJG1lYW5XRApuZXdfZGF0YV9mb3JfQUdCJFdEIDwtIHdvb2RfZGVuc2l0aWVzX25ldyRtZWFuV0QKYGBgCgpgYGB7cn0KZGF0YV9mb3JBR0IKbmV3X2RhdGFfZm9yX0FHQgpgYGAKCgpgYGB7cn0KIyBkYXRhc2V0IOC4guC4reC4h+C5gOC4o+C4siDguKHguLXguJXguYnguJnguYTguKHguYnguIHguLXguYjguJXguYnguJnguJfguLXguYjguYTguJTguYnguITguYjguLIgd29vZCBkZW5zaXR5IOC4iOC4suC4geC5geC4leC5iOC4peC4sOC4o+C4sOC4lOC4seC4miAoc3BlY2llcy9nZW51cy9mYW1pbHkpCnN1bSh3b29kX2RlbnNpdGllc19vbGQkbGV2ZWxXRCA9PSAic3BlY2llcyIpCnN1bSh3b29kX2RlbnNpdGllc19vbGQkbGV2ZWxXRCA9PSAiZ2VudXMiKQpzdW0oIXdvb2RfZGVuc2l0aWVzX29sZCRsZXZlbFdEICVpbiUgYygiZ2VudXMiLCAic3BlY2llcyIpKQpgYGAKCmBgYHtyfQojIGRhdGFzZXQg4LiC4Lit4LiH4LmA4Lij4LiyIOC4oeC4teC4leC5ieC4meC5hOC4oeC5ieC4geC4teC5iOC4leC5ieC4meC4l+C4teC5iOC5hOC4lOC5ieC4hOC5iOC4siB3b29kIGRlbnNpdHkg4LiI4Liy4LiB4LmB4LiV4LmI4Lil4Liw4Lij4Liw4LiU4Lix4LiaIChzcGVjaWVzL2dlbnVzL2ZhbWlseSkKc3VtKHdvb2RfZGVuc2l0aWVzX25ldyRsZXZlbFdEID09ICJzcGVjaWVzIikKc3VtKHdvb2RfZGVuc2l0aWVzX25ldyRsZXZlbFdEID09ICJnZW51cyIpCnN1bSghd29vZF9kZW5zaXRpZXNfbmV3JGxldmVsV0QgJWluJSBjKCJnZW51cyIsICJzcGVjaWVzIikpCmBgYAoKCiNDaGVja2luZyBNaXNzaW5nIFZhbHVlcyBBZnRlciBXb29kIERlbnNpdHkgQXNzaWdubWVudAoKYGBge3J9CiNjaGVjayBtaXNzaW5nIHZhbHVlIOC5geC4leC5iOC4peC4sOC4hOC4reC4peC4seC4oeC4meC5jApjb2xTdW1zKGlzLm5hKGRhdGFfZm9yQUdCKSkKYGBgCmBgYHtyfQojY2hlY2sgbWlzc2luZyB2YWx1ZSDguYHguJXguYjguKXguLDguITguK3guKXguLHguKHguJnguYwKY29sU3Vtcyhpcy5uYShuZXdfZGF0YV9mb3JfQUdCKSkKYGBgCgoKYGBge3J9CiPguJTguLnguKfguYjguLLguKHguLXguYHguJbguKfguYTguKvguJnguJrguYnguLLguIfguJfguLXguYggbWlzc2luZwpkYXRhX2ZvckFHQiAlPiUKICBmaWx0ZXIoaXMubmEoZmFtaWx5QVBHKSB8IGlzLm5hKG9yZGVyQVBHKSkKYGBgCgoKYGBge3J9CnV0bV9jb25uZXIgPC0gcmVhZC5jc3YoIn4vUmVtb3RlLXNlbnNpbmcvREFUQS91dG1fY29ybmVyLmNzdiIpCmhlYWQodXRtX2Nvbm5lcikKYGBgCgpgYGB7cn0KY29ubmVyX2ZpbHRlcmVkIDwtIHV0bV9jb25uZXIgJT4lCiAgZmlsdGVyKFBsb3RfbmFtZSA9PSB1bmlxdWUoZGF0YV9mb3JBR0IkUGxvdF9uYW1lKSAmIFhfbG9jID09IDAgJiBZX2xvYyA9PSAwKQoKaGVhZChjb25uZXJfZmlsdGVyZWQpCmBgYAoKYGBge3J9CnRyZWVfZGF0YV9vbGQgPC0gZGF0YV9mb3JBR0IgJT4lCiAgbGVmdF9qb2luKGNvbm5lcl9maWx0ZXJlZCwgYnkgPSAiUGxvdF9uYW1lIikgJT4lCiAgbXV0YXRlKAogICAgYWJzX3ggPSBYX1VUTSArIFBYLAogICAgYWJzX3kgPSBZX1VUTSArIFBZICAKICApICU+JQogIGRwbHlyOjpzZWxlY3QoYWJzX3gsIGFic195KSAKYGBgCgpgYGB7cn0KdHJlZV9kYXRhX25ldyA8LSBuZXdfZGF0YV9mb3JfQUdCICU+JQogIGxlZnRfam9pbihjb25uZXJfZmlsdGVyZWQsIGJ5ID0gIlBsb3RfbmFtZSIpICU+JQogIG11dGF0ZSgKICAgIGFic194ID0gWF9VVE0gKyBQWCwKICAgIGFic195ID0gWV9VVE0gKyBQWSAgCiAgKSAlPiUKICBkcGx5cjo6c2VsZWN0KGFic194LCBhYnNfeSkgCmBgYAoKCmBgYHtyfQp0cmVlX2RhdGFfb2xkCnRyZWVfZGF0YV9uZXcKYGBgCgpgYGB7cn0Kb2xkX3RyZWVfc2YgPC0gc3RfYXNfc2YodHJlZV9kYXRhX29sZCwgY29vcmRzID0gYygiYWJzX3giLCAiYWJzX3kiKSwgY3JzID0gMzI2NDcpCm5ld190cmVlX3NmIDwtIHN0X2FzX3NmKHRyZWVfZGF0YV9uZXcsIGNvb3JkcyA9IGMoImFic194IiwgImFic195IiksIGNycyA9IDMyNjQ3KQpgYGAKCmBgYHtyfQpvbGRfdHJlZV9sb25nbGF0IDwtIHN0X3RyYW5zZm9ybShvbGRfdHJlZV9zZiwgY3JzID0gNDMyNikKbmV3X3RyZWVfbG9uZ2xhdCA8LSBzdF90cmFuc2Zvcm0obmV3X3RyZWVfc2YsIGNycyA9IDQzMjYpCmBgYAoKYGBge3J9CmNvb3Jkc19sb25nbGF0X29sZCA8LSBzdF9jb29yZGluYXRlcyhvbGRfdHJlZV9sb25nbGF0KQp0cmVlX2RhdGFfb2xkJGxvbiA8LSBjb29yZHNfbG9uZ2xhdF9vbGRbLCAxXQp0cmVlX2RhdGFfb2xkJGxhdCA8LSBjb29yZHNfbG9uZ2xhdF9vbGRbLCAyXQoKY29vcmRzX2xvbmdsYXRfbmV3IDwtIHN0X2Nvb3JkaW5hdGVzKG5ld190cmVlX2xvbmdsYXQpCnRyZWVfZGF0YV9uZXckbG9uIDwtIGNvb3Jkc19sb25nbGF0X25ld1ssIDFdCnRyZWVfZGF0YV9uZXckbGF0IDwtIGNvb3Jkc19sb25nbGF0X25ld1ssIDJdCmBgYAoKYGBge3J9CmNvb3Jkc190cmVlX29sZCA8LSBhcHBseSh0cmVlX2RhdGFfb2xkW2MoImxvbiIsICJsYXQiKV0sIDIsIG1lYW4pCmNvb3Jkc190cmVlX25ldyA8LSBhcHBseSh0cmVlX2RhdGFfbmV3W2MoImxvbiIsICJsYXQiKV0sIDIsIG1lYW4pCmBgYAoKCgojIyBFc3RpbWF0aW5nIFRyZWUgSGVpZ2h0IChIKQoKCmBgYHtyfQpIX2NoYXZlX29sZCA8LSByZXRyaWV2ZUgoCiAgRCA9IGRhdGFfZm9yQUdCJERCSCwKICBjb29yZCA9IGNvb3Jkc190cmVlX29sZAopCmBgYAoKYGBge3J9CkhfY2hhdmVfbmV3IDwtIHJldHJpZXZlSCgKICBEID0gbmV3X2RhdGFfZm9yX0FHQiREQkgsCiAgY29vcmQgPSBjb29yZHNfdHJlZV9uZXcKKQpgYGAKCgpgYGB7cn0KZGF0YV9mb3JBR0IkSF9jaGF2ZSA8LSBIX2NoYXZlX29sZCRICm5ld19kYXRhX2Zvcl9BR0IkSF9jaGF2ZSA8LSBIX2NoYXZlX25ldyRICmBgYAoKCmBgYHtyfQpvbGRfSERfbW9kZWwgPC0gbW9kZWxIRCgKICBEID0gZGF0YV9mb3JBR0IkREJILAogIEggPSBkYXRhX2ZvckFHQiRIX2NoYXZlLAogIG1ldGhvZCA9ICJsb2cyIiwKICB1c2VXZWlnaHQgPSBUUlVFCikKYGBgCgpgYGB7cn0KbmV3X0hEX21vZGVsIDwtIG1vZGVsSEQoCiAgRCA9IG5ld19kYXRhX2Zvcl9BR0IkREJILAogIEggPSBuZXdfZGF0YV9mb3JfQUdCJEhfY2hhdmUsCiAgbWV0aG9kID0gImxvZzIiLAogIHVzZVdlaWdodCA9IFRSVUUKKQpgYGAKCgojIyBDb21wdXRpbmcgQWJvdmUgR3JvdW5kIEJpb21hc3MgKEFHQikKCmBgYHtyfQpkYXRhX2ZvckFHQiRBR0IgPC0gY29tcHV0ZUFHQigKICBEID0gZGF0YV9mb3JBR0IkREJILAogIFdEID0gZGF0YV9mb3JBR0IkV0QsCiAgSCA9IGRhdGFfZm9yQUdCJEhfY2hhdmUgCikKCm5ld19kYXRhX2Zvcl9BR0IkQUdCIDwtIGNvbXB1dGVBR0IoCiAgRCA9IG5ld19kYXRhX2Zvcl9BR0IkREJILAogIFdEID0gbmV3X2RhdGFfZm9yX0FHQiRXRCwKICBIID0gbmV3X2RhdGFfZm9yX0FHQiRIX2NoYXZlIAopCmBgYAoKIyMgUHJvcGFnYXRpbmcgRXJyb3JzIGluIEFHQiBFc3RpbWF0aW9uIChNb250ZSBDYXJsbykKCmBgYHtyfQpEX2Vycm9yX3Byb3Bfb2xkIDwtIEFHQm1vbnRlQ2FybG8oCiAgRCA9IGRhdGFfZm9yQUdCJERCSCwgV0QgPSBkYXRhX2ZvckFHQiRXRCwgSCA9IGRhdGFfZm9yQUdCJEhfY2hhdmUsCiAgRHByb3BhZyA9ICJjaGF2ZTIwMDQiLAogIGVycldEID0gcmVwKDAsbnJvdyhkYXRhX2ZvckFHQikpLCBlcnJIID0gMCAKKQoKRF9lcnJvcl9wcm9wX25ldyA8LSBBR0Jtb250ZUNhcmxvKAogIEQgPSBuZXdfZGF0YV9mb3JfQUdCJERCSCwgV0QgPSBuZXdfZGF0YV9mb3JfQUdCJFdELCBIID0gbmV3X2RhdGFfZm9yX0FHQiRIX2NoYXZlLAogIERwcm9wYWcgPSAiY2hhdmUyMDA0IiwKICBlcnJXRCA9IHJlcCgwLG5yb3cobmV3X2RhdGFfZm9yX0FHQikpLCBlcnJIID0gMCAKKQpgYGAKCmBgYHtyfQpuZXdfZGF0YV9mb3JfQUdCCmBgYAoKCmBgYHtyfQpXRF9lcnJvcl9wcm9wX29sZCA8LSBBR0Jtb250ZUNhcmxvKAogIEQgPSBkYXRhX2ZvckFHQiREQkgsIFdEID0gZGF0YV9mb3JBR0IkV0QsIEggPSBkYXRhX2ZvckFHQiRIX2NoYXZlLAogIGVycldEID0gd29vZF9kZW5zaXRpZXNfb2xkJHNkV0QsCiAgRHByb3BhZyA9IDAgLCBlcnJIID0gMCAKKQoKV0RfZXJyb3JfcHJvcF9uZXcgPC0gQUdCbW9udGVDYXJsbygKICBEID0gbmV3X2RhdGFfZm9yX0FHQiREQkgsIFdEID0gbmV3X2RhdGFfZm9yX0FHQiRXRCwgSCA9IG5ld19kYXRhX2Zvcl9BR0IkSF9jaGF2ZSwKICBlcnJXRCA9IHdvb2RfZGVuc2l0aWVzX25ldyRzZFdELAogIERwcm9wYWcgPSAwICwgZXJySCA9IDAgCikKYGBgCgpgYGB7cn0KSF9tb2RlbF9lcnJvcl9wcm9wX29sZCA8LSBBR0Jtb250ZUNhcmxvKAogIEQgPSBkYXRhX2ZvckFHQiREQkgsIFdEID0gZGF0YV9mb3JBR0IkV0QsIAogIEhEbW9kZWwgPSBIRF9tb2RlbCwgCiAgRHByb3BhZyA9IDAgLCBlcnJXRCA9IHJlcCgwLG5yb3coZGF0YV9mb3JBR0IpKSAKKQoKSF9tb2RlbF9lcnJvcl9wcm9wX25ldyA8LSBBR0Jtb250ZUNhcmxvKAogIEQgPSBuZXdfZGF0YV9mb3JfQUdCJERCSCwgV0QgPSBuZXdfZGF0YV9mb3JfQUdCJFdELCAKICBIRG1vZGVsID0gSERfbW9kZWwsIAogIERwcm9wYWcgPSAwICwgZXJyV0QgPSByZXAoMCxucm93KG5ld19kYXRhX2Zvcl9BR0IpKSAKKQoKYGBgCgpgYGB7cn0KZXJyb3JfcHJvcF9vbGQgPC0gQUdCbW9udGVDYXJsbygKICBEID0gZGF0YV9mb3JBR0IkREJILAogIFdEID0gIGRhdGFfZm9yQUdCJFdELCAgICAgICAgCiAgSCA9ICBkYXRhX2ZvckFHQiRIX2NoYXZlLCAKICBEcHJvcGFnID0gImNoYXZlMjAwNCIsICAgICAgICAgICAKICBlcnJXRCA9IHdvb2RfZGVuc2l0aWVzX29sZCRzZFdELCAgICAKICBlcnJIID0gSF9tb2RlbF9lcnJvcl9wcm9wX29sZCRzZEFHQgopCgplcnJvcl9wcm9wX25ldyA8LSBBR0Jtb250ZUNhcmxvKAogIEQgPSBuZXdfZGF0YV9mb3JfQUdCJERCSCwKICBXRCA9ICBuZXdfZGF0YV9mb3JfQUdCJFdELCAgICAgICAgCiAgSCA9ICBuZXdfZGF0YV9mb3JfQUdCJEhfY2hhdmUsIAogIERwcm9wYWcgPSAiY2hhdmUyMDA0IiwgICAgICAgICAgIAogIGVycldEID0gd29vZF9kZW5zaXRpZXNfbmV3JHNkV0QsICAgIAogIGVyckggPSBIX21vZGVsX2Vycm9yX3Byb3BfbmV3JHNkQUdCCikKYGBgCgpgYGB7cn0KZXJyb3JfcHJvcF9vbGRbKDE6NCldCnN1bShkYXRhX2ZvckFHQiRBR0IpCmBgYApgYGB7cn0KZXJyb3JfcHJvcF9uZXdbKDE6NCldCnN1bShuZXdfZGF0YV9mb3JfQUdCJEFHQikKYGBgCgoKYGBge3J9Cm9sZF9BR0JfYnlfcGxvdCA8LSBzdW1tYXJ5QnlQbG90KEFHQl92YWwgPSBlcnJvcl9wcm9wX29sZCRBR0Jfc2ltdSwgcGxvdCA9IGRhdGFfZm9yQUdCJFBsb3RfbmFtZSwgZHJhd1Bsb3QgPSBUUlVFKQpuZXdfQUdCX2J5X3Bsb3QgPC0gc3VtbWFyeUJ5UGxvdChBR0JfdmFsID0gZXJyb3JfcHJvcF9uZXckQUdCX3NpbXUsIHBsb3QgPSBuZXdfZGF0YV9mb3JfQUdCJFBsb3RfbmFtZSwgZHJhd1Bsb3QgPSBUUlVFKQpgYGAKCgojIyBQbG90IFNwYXRpYWwgQ29uZmlndXJhdGlvbiBhbmQgU3VicGxvdCBEaXZpc2lvbgoKYGBge3J9ClJhbm9uZ19wbG90X2Nvcm5lciA8LSB1dG1fY29ubmVyW3V0bV9jb25uZXIkUGxvdF9uYW1lID09ICJMYS11biAoUmFub25nKSIsXQpgYGAKCmBgYHtyfQpSYW5vbmdfcGxvdF9jb3JuZXIKYGBgCgoKYGBge3J9CmZpZWxkcGxvdCA8LSBjaGVja19wbG90X2Nvb3JkKAogIGNvcm5lcl9kYXRhID0gIFJhbm9uZ19wbG90X2Nvcm5lciwKICBwcm9qX2Nvb3JkID0gYygiWF9VVE0iLCAiWV9VVE0iKSwgIAogIHJlbF9jb29yZCA9IGMoIlhfbG9jIiwgIllfbG9jIiksCiAgcGxvdF9JRCA9ICJQbG90X25hbWUiLAogIHRydXN0X0dQU19jb3JuZXJzID0gRkFMU0UsCiAgZHJhd19wbG90ID0gVFJVRSwgcm1fb3V0bGllcnMgPSBGQUxTRSkKYGBgCgpgYGB7cn0KZmllbGRwbG90X29sZCA8LSBjaGVja19wbG90X2Nvb3JkKAogIGNvcm5lcl9kYXRhID0gIFJhbm9uZ19wbG90X2Nvcm5lciwKICBwcm9qX2Nvb3JkID0gYygiWF9VVE0iLCAiWV9VVE0iKSwgIAogIHJlbF9jb29yZCA9IGMoIlhfbG9jIiwgIllfbG9jIiksCiAgcGxvdF9JRCA9ICJQbG90X25hbWUiLCAgICAgICAgICAgICAgICAgICAgICAKICB0cnVzdF9HUFNfY29ybmVycyA9IEZBTFNFLAogIHRyZWVfZGF0YSA9IGRhdGFfZm9yQUdCLAogIHRyZWVfY29vcmRzID0gYygiUFgiLCAiUFkiKSwKICB0cmVlX3Bsb3RfSUQgPSAiUGxvdF9uYW1lIiwgICAgICAgICAgIAogIGRyYXdfcGxvdCA9IFRSVUUsIAogIHJtX291dGxpZXJzID0gRkFMU0UKKQpgYGAKYGBge3J9CmZpZWxkcGxvdF9uZXcgPC0gY2hlY2tfcGxvdF9jb29yZCgKICBjb3JuZXJfZGF0YSA9ICBSYW5vbmdfcGxvdF9jb3JuZXIsCiAgcHJval9jb29yZCA9IGMoIlhfVVRNIiwgIllfVVRNIiksICAKICByZWxfY29vcmQgPSBjKCJYX2xvYyIsICJZX2xvYyIpLAogIHBsb3RfSUQgPSAiUGxvdF9uYW1lIiwgICAgICAgICAgICAgICAgICAgICAgCiAgdHJ1c3RfR1BTX2Nvcm5lcnMgPSBGQUxTRSwKICB0cmVlX2RhdGEgPSBuZXdfZGF0YV9mb3JfQUdCLAogIHRyZWVfY29vcmRzID0gYygiUFgiLCAiUFkiKSwKICB0cmVlX3Bsb3RfSUQgPSAiUGxvdF9uYW1lIiwgICAgICAgICAgIAogIGRyYXdfcGxvdCA9IFRSVUUsIAogIHJtX291dGxpZXJzID0gRkFMU0UKKQpgYGAKCgpgYGB7cn0Kc3Rfd3JpdGUoCiAgb2JqID0gZmllbGRwbG90X29sZCRwb2x5Z29uLAogIGRzbiA9ICJ+L1JlbW90ZS1zZW5zaW5nL1Jhbm9uZ19maWVsZHBsb3Rfb2xkLnNocCIsCiAgZGVsZXRlX2xheWVyID0gVFJVRQopCmBgYApgYGB7cn0Kc3Rfd3JpdGUoCiAgb2JqID0gZmllbGRwbG90X25ldyRwb2x5Z29uLAogIGRzbiA9ICJ+L1JlbW90ZS1zZW5zaW5nL1Jhbm9uZ19maWVsZHBsb3RfbmV3LnNocCIsCiAgZGVsZXRlX2xheWVyID0gVFJVRQopCmBgYAoKYGBge3J9CiMgMjB4MjAKc3VicGxvdHNfZ3JpZDIwX29sZCA8LSBkaXZpZGVfcGxvdCgKICBjb3JuZXJfZGF0YSA9IGZpZWxkcGxvdF9vbGQkY29ybmVyX2Nvb3JkLCAKICByZWxfY29vcmQgPSBjKCJ4X3JlbCIsInlfcmVsIiksCiAgcHJval9jb29yZCA9IGMoInhfcHJvaiIsInlfcHJvaiIpLAogIGdyaWRfc2l6ZSA9IDIwLAogIHRyZWVfZGF0YSA9IGRhdGFfZm9yQUdCLCAKICB0cmVlX2Nvb3JkcyA9IGMoIlBYIiwiUFkiKQopCgojNTB4NTAKc3VicGxvdHNfZ3JpZDUwX29sZCA8LSBkaXZpZGVfcGxvdCgKICBjb3JuZXJfZGF0YSA9IGZpZWxkcGxvdF9vbGQkY29ybmVyX2Nvb3JkLCAKICByZWxfY29vcmQgPSBjKCJ4X3JlbCIsInlfcmVsIiksCiAgcHJval9jb29yZCA9IGMoInhfcHJvaiIsInlfcHJvaiIpLAogIGdyaWRfc2l6ZSA9IDUwLAogIHRyZWVfZGF0YSA9IGRhdGFfZm9yQUdCLCAKICB0cmVlX2Nvb3JkcyA9IGMoIlBYIiwiUFkiKQopCgoKYGBgCgpgYGB7cn0KIyAyMHgyMApzdWJwbG90c19ncmlkMjBfbmV3IDwtIGRpdmlkZV9wbG90KAogIGNvcm5lcl9kYXRhID0gZmllbGRwbG90X25ldyRjb3JuZXJfY29vcmQsIAogIHJlbF9jb29yZCA9IGMoInhfcmVsIiwieV9yZWwiKSwKICBwcm9qX2Nvb3JkID0gYygieF9wcm9qIiwieV9wcm9qIiksCiAgZ3JpZF9zaXplID0gMjAsCiAgdHJlZV9kYXRhID0gbmV3X2RhdGFfZm9yX0FHQiwgCiAgdHJlZV9jb29yZHMgPSBjKCJQWCIsIlBZIikKKQoKIzUweDUwCnN1YnBsb3RzX2dyaWQ1MF9uZXcgPC0gZGl2aWRlX3Bsb3QoCiAgY29ybmVyX2RhdGEgPSBmaWVsZHBsb3Rfb2xkJGNvcm5lcl9jb29yZCwgCiAgcmVsX2Nvb3JkID0gYygieF9yZWwiLCJ5X3JlbCIpLAogIHByb2pfY29vcmQgPSBjKCJ4X3Byb2oiLCJ5X3Byb2oiKSwKICBncmlkX3NpemUgPSA1MCwKICB0cmVlX2RhdGEgPSBkYXRhX2ZvckFHQiwgCiAgdHJlZV9jb29yZHMgPSBjKCJQWCIsIlBZIikKKQpgYGAKCgpgYGB7cn0Kc3VicGxvdF9tZXRyaWNfcGVySEEyMF9vbGQgPC0gc3VicGxvdF9zdW1tYXJ5KAogIHN1YnBsb3RzID0gc3VicGxvdHNfZ3JpZDIwX29sZCwKICB2YWx1ZSA9ICJBR0IiLCAKICBwZXJfaGEgPSBUUlVFKQoKYGBgCgoKCmBgYHtyfQpzdWJwbG90X21ldHJpY19wZXJIQTIwX25ldyA8LSBzdWJwbG90X3N1bW1hcnkoCiAgc3VicGxvdHMgPSBzdWJwbG90c19ncmlkMjBfbmV3LAogIHZhbHVlID0gIkFHQiIsIAogIHBlcl9oYSA9IFRSVUUpCmBgYAoKYGBge3J9CnN1YnBsb3RfbWV0cmljX3BlckhBNTBfb2xkIDwtIHN1YnBsb3Rfc3VtbWFyeSgKICBzdWJwbG90cyA9IHN1YnBsb3RzX2dyaWQ1MF9vbGQsCiAgdmFsdWUgPSAiQUdCIiwgCiAgcGVyX2hhID0gVFJVRSkKYGBgCgpgYGB7cn0Kc3VicGxvdF9tZXRyaWNfcGVySEE1MF9uZXcgPC0gc3VicGxvdF9zdW1tYXJ5KAogIHN1YnBsb3RzID0gc3VicGxvdHNfZ3JpZDUwX25ldywKICB2YWx1ZSA9ICJBR0IiLCAKICBwZXJfaGEgPSBUUlVFKQpgYGAKCgpgYGB7cn0KY3VzdG9tX3Bsb3RfcGVySEEyMF9vbGQgPC0gc3VicGxvdF9tZXRyaWNfcGVySEEyMF9vbGQkcGxvdF9kZXNpZ24gKwogIHNjYWxlX2ZpbGxfZGlzdGlsbGVyKHBhbGV0dGUgPSAiWWxHbkJ1IiwgZGlyZWN0aW9uID0gMSkgCgpjdXN0b21fcGxvdF9wZXJIQTIwX29sZAoKc2Y6OnN0X3dyaXRlKGN1c3RvbV9wbG90X3BlckhBMjBfb2xkLCJ+L1JlbW90ZS1zZW5zaW5nL3BvbHlnb25fMjBtX3BlckhBLnNocCIpCmBgYApgYGB7cn0KY3VzdG9tX3Bsb3RfcGVySEEyMF9uZXcgPC0gc3VicGxvdF9tZXRyaWNfcGVySEEyMF9uZXckcGxvdF9kZXNpZ24gKwogIHNjYWxlX2ZpbGxfZGlzdGlsbGVyKHBhbGV0dGUgPSAiWWxHbkJ1IiwgZGlyZWN0aW9uID0gMSkKCmN1c3RvbV9wbG90X3BlckhBMjBfbmV3CgpgYGAKCmBgYHtyfQpzdWJwbG90X3BvbHlnb25zMjBtX3BlckhBIDwtIHNmOjpzdF9zZXRfY3JzKAogc3VicGxvdF9tZXRyaWNfcGVySEEyMF9uZXckcG9seWdvbiAsCiAgdmFsdWUgPSAiRVBTRzozMjY0NyIpIAoKc2Y6OnN0X3dyaXRlKHN1YnBsb3RfcG9seWdvbnMyMG1fcGVySEEsIn4vUmVtb3RlLXNlbnNpbmcvcG9seWdvbl8yMG1fcGVySEEuc2hwIikKYGBgCgoKYGBge3J9CmN1c3RvbV9wbG90X3BlckhBNTBfb2xkIDwtIHN1YnBsb3RfbWV0cmljX3BlckhBNTBfb2xkJHBsb3RfZGVzaWduICsKICBzY2FsZV9maWxsX2Rpc3RpbGxlcihwYWxldHRlID0gIllsR25CdSIsIGRpcmVjdGlvbiA9IDEpIAoKY3VzdG9tX3Bsb3RfcGVySEE1MF9vbGQKYGBgCgpgYGB7cn0KY3VzdG9tX3Bsb3RfcGVySEE1MF9uZXcgPC0gc3VicGxvdF9tZXRyaWNfcGVySEE1MF9uZXckcGxvdF9kZXNpZ24gKwogIHNjYWxlX2ZpbGxfZGlzdGlsbGVyKHBhbGV0dGUgPSAiWWxHbkJ1IiwgZGlyZWN0aW9uID0gMSkKCmN1c3RvbV9wbG90X3BlckhBNTBfbmV3CmBgYAoKYGBge3J9CnN1YnBsb3RfbWV0cmljX3N1bTIwX29sZDwtIHN1YnBsb3Rfc3VtbWFyeSgKICBzdWJwbG90cyA9IHN1YnBsb3RzX2dyaWQyMF9vbGQsCiAgdmFsdWUgPSAiQUdCIiwKICBmdW4gPSBxdWFudGlsZSwgcHJvYnMgPSAwLjUsIAogIHBlcl9oYSA9IEZBTFNFKQpgYGAKYGBge3J9CmN1c3RvbV9wbG90X3F0IDwtIHN1YnBsb3RfbWV0cmljX3N1bTIwX29sZCRwbG90X2Rlc2lnbiArCiAgc2NhbGVfZmlsbF9kaXN0aWxsZXIocGFsZXR0ZSA9ICJZbEduQnUiLCBkaXJlY3Rpb24gPSAxKQoKY3VzdG9tX3Bsb3RfcXQKYGBgCgoKCgo=